package com.cloud.alibaba.common.util;

import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Splitter;
import org.springframework.util.StringUtils;

import java.security.SecureRandom;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author taoxinhuan
 * @description: 自己慢慢收集的字符串工具类，非常好用
 * @date 2020/9/1 14:56
 */
public class StringUtil {
    private static String dictionaryChar = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-?$%#!^";

    private static String defaultChar = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

    public static boolean isEmpty(String str) {
        return (str == null) || (str.trim().equals(""));
    }

    public static String getTimestamp() {
        SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMddHHmmss");
        return fmt.format(new Date());
    }

    public static String getRandomNum(int size) {
        String random = new StringBuilder().append((int) (Math.random() * Math.pow(10.0D, size))).append("").toString();
        int length = random.length();
        if (length < size) {
            random = new StringBuilder().append("0").append(random).toString();
            length++;
        }
        return random;
    }

    public static String getRandomKey32() {
        StringBuilder sb = new StringBuilder(32);
        SecureRandom random = new SecureRandom();
        for (int i = 0; i < 32; i++) {
            sb.append(dictionaryChar.charAt(random.nextInt(dictionaryChar.length())));
        }
        return sb.toString();
    }

    public static String getRandomKey(int length) {
        StringBuilder sb = new StringBuilder(length);
        SecureRandom random = new SecureRandom();
        for (int i = 0; i < length; i++) {
            sb.append(defaultChar.charAt(random.nextInt(defaultChar.length())));
        }
        return sb.toString();
    }

    /**
     * 生成随机字符字符串
     *
     * @param chars  指定字符集
     * @param length 长度
     */
    public static String getRandomKey(String chars, int length) {
        StringBuilder sb = new StringBuilder(length);
        SecureRandom random = new SecureRandom();
        int charsLength = chars.length();
        for (int i = 0; i < length; i++) {
            sb.append(chars.charAt(random.nextInt(charsLength)));
        }
        return sb.toString();
    }

    /**
     * 生成随机字符字符串
     *
     * @param chars      指定字符集
     * @param startChars 指定开头字符
     * @param length     长度
     */
    public static String getRandomKey(String chars, String startChars, int length) {
        StringBuilder sb = new StringBuilder(length);
        SecureRandom random = new SecureRandom();
        sb.append(startChars);
        int startCharsLength = startChars.length();
        int size = length - startCharsLength;
        int charsLength = chars.length();
        for (int i = 0; i < size; i++) {
            sb.append(chars.charAt(random.nextInt(charsLength)));
        }
        return sb.toString();
    }

    /**
     * 验证手机号
     */
    public static boolean isMobile(String mobile) {
        if (isEmpty(mobile))
            return false;
//		Pattern p = Pattern.compile("^((13[0-9])|(14[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$");
        Pattern p = Pattern.compile("^(13|14|15|16|17|18|19)[0-9]{9}$");
        Matcher m = p.matcher(mobile);
        return m.matches();
    }

    /**
     * 验证座机
     */
    public static boolean isPhone(String mobile) {
        if (isEmpty(mobile))
            return false;
//		Pattern p = Pattern.compile("^((13[0-9])|(14[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$");
        Pattern p = Pattern.compile("^0\\d{2,3}-?\\d{7,8}$");
        Matcher m = p.matcher(mobile);
        return m.matches();
    }

    /**
     * 验证中文名
     *
     * @param minLen 不少于minLen个字符
     * @param maxLen 不超过maxLen个字符
     */
    public static boolean isChineseName(String name, int minLen, int maxLen) {
        if (isEmpty(name))
            return false;
        if (name.length() < minLen || name.length() > maxLen)
            return false;
        Pattern p = Pattern.compile("[\u4e00-\u9fa5]+");
        Matcher m = p.matcher(name);
        return m.matches();
    }

    /**
     * 验证英文名
     *
     * @param minLen 不少于minLen个字符
     * @param maxLen 不超过maxLen个字符
     */
    public static boolean isEnglishName(String name, int minLen, int maxLen) {
        if (isEmpty(name))
            return false;
        if (name.length() < minLen || name.length() > maxLen)
            return false;
        Pattern p = Pattern.compile("[A-Za-z·]+");
        Matcher m = p.matcher(name);
        return m.matches();
    }

    /**
     * 验证只能是英文名和中文名
     */
    public static boolean isEnglishNameAndChina(String name) {
        if (isEmpty(name))
            return false;
        String str = "^[\u4e00-\u9fa5]{1,5}$|^[A-Za-z]{1,50}$";
        Pattern p = Pattern.compile(str);
        Matcher m = p.matcher(name);
        return m.matches();
    }

    /**
     * 32位长度UUID
     */
    public static String getUUID32() {
        return UUID.randomUUID().toString().replaceAll("-", "");
    }

    /**
     * 16位长度UUID
     */
    public static String getUUID16() {
        return getUUID32().substring(0, 16);
    }

    /**
     * 指定长度UUID
     *
     * @param length 必须小于等于32
     */
    public static String getUUID(int length) {
        return getUUID32().substring(0, length);
    }

    /**
     * 验证时间字符串格式输入是否正确 yyyy-MM-dd HH:mm:ss
     */
    public static boolean valiDateTimeWithLongFormat(String timeStr) {
        String format = "((19|20)[0-9]{2})-(0?[1-9]|1[012])-(0?[1-9]|[12][0-9]|3[01]) "
                + "([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]";
        Pattern pattern = Pattern.compile(format);
        Matcher matcher = pattern.matcher(timeStr);
        if (matcher.matches()) {
            pattern = Pattern.compile("(\\d{4})-(\\d+)-(\\d+).*");
            matcher = pattern.matcher(timeStr);
            if (matcher.matches()) {
                int y = Integer.valueOf(matcher.group(1));
                int m = Integer.valueOf(matcher.group(2));
                int d = Integer.valueOf(matcher.group(3));
                if (d > 28) {
                    Calendar c = Calendar.getInstance();
                    c.set(y, m - 1, 1);
                    int lastDay = c.getActualMaximum(Calendar.DAY_OF_MONTH);
                    return (lastDay >= d);
                }
            }
            return true;
        }
        return false;
    }

    /**
     * 验证时间字符串格式输入是否正确 yyyy-MM-dd
     */
    public static boolean valiDateTime(String timeStr) {
        String format = "((19|20)[0-9]{2})-(0?[1-9]|1[012])-(0?[1-9]|[12][0-9]|3[01])";
        Pattern pattern = Pattern.compile(format);
        Matcher matcher = pattern.matcher(timeStr);
        if (matcher.matches()) {
            pattern = Pattern.compile("(\\d{4})-(\\d+)-(\\d+).*");
            matcher = pattern.matcher(timeStr);
            if (matcher.matches()) {
                int y = Integer.valueOf(matcher.group(1));
                int m = Integer.valueOf(matcher.group(2));
                int d = Integer.valueOf(matcher.group(3));
                if (d > 28) {
                    Calendar c = Calendar.getInstance();
                    c.set(y, m - 1, 1);
                    int lastDay = c.getActualMaximum(Calendar.DAY_OF_MONTH);
                    return (lastDay >= d);
                }
            }
            return true;
        }
        return false;
    }

    /**
     * uri后面添加参数
     */
    public static String uriAppendParam(String uri, String key, Object val) {

        String result = uri;
        // 防止参数重复添加
        if (!uri.contains(key + "=")) {
            if (uri.contains("?")) {
                result += "&" + key + "=" + val;
            } else {
                result += "?" + key + "=" + val;
            }
        }
        return result;
    }

    /**
     * uri后面批量添加参数
     */
    public static String uriAppendParams(String uri, Map<String, Object> params) {

        String result = uri;

        Set<String> keys = params.keySet();
        for (String key : keys) {
            result = uriAppendParam(result, key, params.get(key));
        }
        return result;
    }

    /**
     * uri后面批量添加参数
     */
    public static String uriAppendParams(String uri, JSONObject json) {

        String result = uri;

        Set<String> keys = json.keySet();
        for (String key : keys) {
            result = uriAppendParam(result, key, json.get(key));
        }
        return result;
    }


    public static String trim(String origin, char trim) {
        if (StringUtils.hasText(origin)) {
            return "";
        }
        int st = 0;
        int len = origin.length();
        char[] val = origin.toCharArray();
        while ((st < len) && (val[st] == trim)) {
            st++;
        }
        while ((st < len) && (val[len - 1] == trim)) {
            len--;
        }
        return ((st > 0) || (len < origin.length())) ? origin.substring(st, len) : origin;
    }

    /**
     * 将字符串text中由openToken和closeToken组成的占位符依次替换为args数组中的值
     *
     * @param openToken
     * @param closeToken
     * @param text
     * @param args
     * @return
     */
    public static String parse(String openToken, String closeToken, String text, Object... args) {
        if (!StringUtils.hasText(text)) {
            return "";
        }
        if (args == null || args.length <= 0) {
            return text;
        }
        int offset = 0;
        int start = text.indexOf(openToken, offset);
        int close = text.indexOf(closeToken, offset);
        //如果不存在直接替换目标开始结尾直接返回原字符串
        if (start == -1 || close == -1) {
            return text;
        }
        int argsIndex = 0;
        char[] textCharArray = text.toCharArray();
        final StringBuilder builder = new StringBuilder();
        StringBuilder expression = null;
        while (start > -1) {
            if (start > 0 && textCharArray[start - 1] == '\\') {
                // this open token is escaped. remove the backslash and continue.
                builder.append(textCharArray, offset, start - offset - 1).append(openToken);
                offset = start + openToken.length();
            } else {
                if (expression == null) {
                    expression = new StringBuilder();
                } else {
                    expression.setLength(0);
                }
                builder.append(textCharArray, offset, start - offset);
                offset = start + openToken.length();
                int end = text.indexOf(closeToken, offset);
                while (end > -1) {
                    if (end > offset && textCharArray[end - 1] == '\\') {
                        expression.append(textCharArray, offset, end - offset - 1).append(closeToken);
                        offset = end + closeToken.length();
                        end = text.indexOf(closeToken, offset);
                    } else {
                        expression.append(textCharArray, offset, end - offset);
                        break;
                    }
                }
                if (end == -1) {
                    // close token was not found.
                    builder.append(textCharArray, start, textCharArray.length - start);
                    offset = textCharArray.length;
                } else {
                    String value = argsIndex <= args.length - 1 ?
                            (args[argsIndex] == null ? "" : args[argsIndex].toString()) : expression.toString();
                    builder.append(value);
                    offset = end + closeToken.length();
                    argsIndex++;
                }
            }
            start = text.indexOf(openToken, offset);
        }
        if (offset < textCharArray.length) {
            builder.append(textCharArray, offset, textCharArray.length - offset);
        }
        return builder.toString();
    }

    public static String format(String text, Object... args) {
        return StringUtil.parse("{", "}", text, args);
    }

    public static List stringToLongList(String str){
        List<Long> ids=new ArrayList<>();
        if(StringUtils.hasText(str)){
            ids = Splitter.on(',').trimResults().omitEmptyStrings().splitToList(str).stream().map(s -> {
                return Long.valueOf(s);
            }).collect(Collectors.toList());
        }
        return ids;
    }

    public static void main(String[] args) {
        String str="@font-face {  font-family: 'Abril Fatface';  font-style: normal;  font-weight: 400;  src: url(https://fonts.gstatic.com/s/abrilfatface/v12/zOL64pLDlL1D99S8g8PtiKchq-dmiA.ttf) format('truetype');}";
        String openToken="src: url(";
        String closeToken=") format('truetype')";
        String replaceResult = StringUtil.parse(openToken, closeToken, str,openToken+"https://www.baidu.com/"+closeToken);
        int begin = str.indexOf(openToken);
        int end = str.indexOf(closeToken);
        String substring = str.substring(begin+9, end);
        System.out.println("切割Url结果为："+substring);
        System.out.println("替换Url结果为："+replaceResult);
        List list = stringToLongList("1,2,3");
        List list2 = stringToLongList("");
        System.out.println(list);
        System.out.println(list2);
    }

}
